<?php

/**
 * Description of Page
 *
 * @author bonfiglio
 */
class Page {

    public $version = '0.1';
    private $token = '';
    public $options = array();
    public $browser;
    protected $defaultVersionModernizr = '2.6.2';
    private $versionsModernizr = array('2.6.2');
    private $versionModernizr;
    protected $defaultVersionBootstrap = '2.0.4';
    private $versionsBootstrap = array('2.0.4', '2.1.1', '2.2.1', '2.3.0', '2.3.1');
    private $versionBootstrap;
    private $bootstrapByCDN = false;
    private $versionsJquery = array('1.4.4', '1.8.0', '1.9.1');
    private $versionJquery;
    public $currentPage = '';

    public function __construct($options = array()) {

        $this->options['debug'] = array_key_exists('debug', $options) ? $options['debug'] : DEBUG;

        $this->options['host'] = 'http://' . $_SERVER['HTTP_HOST'] . '/';

        $this->options['relative_path'] = (isset($options['relative_path']) && !empty($options['relative_path'])) ? $options['relative_path'] : '';

        $this->options['favicon'] = (isset($options['favicon']) && !empty($options['favicon'])) ? $options['favicon'] : false;

        $this->options['base_url'] = (isset($options['base_url']) && !empty($options['base_url'])) ? $options['base_url'] : $this->options['host'];

        if (substr($this->options['base_url'], -1) != '/') {
            $this->options['base_url'] .= '/';
        }

        $final = '';

        if (!isset($options['base_engine'])) {
            $a = explode('/', ENGINE_ROOT);
            $b = explode('/', DOCUMENT_ROOT);
            $subfolder = str_replace(DOCUMENT_ROOT, '', ENGINE_ROOT);
            $final = array();
            if (strlen($subfolder) < strlen(ENGINE_ROOT)) {
                $final = $subfolder;
            } else {
                foreach ($a as $k => $v) {
                    if (isset($b[$k]) && $b[$k] != $v) {
                        $final[] = $v;
                    }
                }
                $final = implode('/', $final);
            }


            if (substr($final, -1) != '/') {
                $final .= '/';
            }
            if (substr($final, 0, 1) == '/') {
                $final = substr($final, 1, strlen($final) - 1);
            }
            $final = $this->options['base_url'] . $final;
        } else {
            $final = $options['base_engine'];
        }
        $this->options['base_engine'] = $final;

        $this->options['bridge'] = array_key_exists('bridge', $options) ? (boolean) $options['bridge'] : true;

        $this->options['version'] = (isset($options['version']) && !empty($options['version'])) ? $options['version'] : $this->version;

        $this->options['default_title'] = (isset($options['default_title']) && !empty($options['default_title'])) ? $options['default_title'] : '';

        $this->options['meta_description'] = (isset($options['meta_description']) && !empty($options['meta_description'])) ? $options['meta_description'] : '';

        $this->options['meta_keywords'] = (isset($options['meta_keywords']) && !empty($options['meta_keywords'])) ? $options['meta_keywords'] : '';

        $this->options['content_type'] = (isset($options['content_type']) && !empty($options['content_type'])) ? $options['content_type'] : false;

        $this->options['title'] = (isset($options['title']) && !empty($options['title'])) ? $options['title'] : '';

        $this->options['robot'] = (array_key_exists('robot', $options)) ? (boolean) $options['robot'] : true;

        $this->options['robots'] = (isset($options['robots']) && !empty($options['robots'])) ? $options['robots'] : '';

        $this->options['responsive'] = (array_key_exists('responsive', $options)) ? (boolean) $options['responsive'] : true;

        $this->options['browser_update'] = array_key_exists('browser_update', $options) ? filter_var($options['browser_update'], FILTER_VALIDATE_BOOLEAN) : true;

        $this->options['bootstrap'] = array_key_exists('bootstrap', $options) ? $options['bootstrap'] : true;

        $this->options['BootstrapTwitterJS'] = $this->options['bootstrap'] && array_key_exists('BootstrapTwitterJS', $options);

        $this->options['bootstrapByCDN'] = array_key_exists('bootstrapByCDN', $options) ? $options['bootstrapByCDN'] : $this->bootstrapByCDN;

        $this->options['bootstrapFontAwesomeByCND'] = array_key_exists('bootstrapFontAwesomeByCND', $options) ? $options['bootstrapFontAwesomeByCND'] : false;

        $this->versionBootstrap = in_array($this->options['bootstrap'], $this->versionsBootstrap) && $this->options['bootstrap'] !== true ? $this->options['bootstrap'] : $this->defaultVersionBootstrap;

        $this->options['jquery'] = array_key_exists('jquery', $options) ? $options['jquery'] : true;

        //http://code.jquery.com/jquery-migrate-1.2.1.js

        $this->options['jquery_migrate'] = $this->options['jquery'] && array_key_exists('jquery_migrate', $options) ? $options['jquery_migrate'] : false;

        $this->versionJquery = in_array($this->options['jquery'], $this->versionsJquery) && $this->options['jquery'] !== true ? $this->options['jquery'] : $this->versionsJquery[0]; // on prend la premiere par default

        $this->options['jquery_mobile'] = array_key_exists('jquery_mobile', $options) ? filter_var($options['jquery_mobile']) : false;

        $this->options['jquery_ui'] = array_key_exists('jquery_ui', $options) ? filter_var($options['jquery_ui']) : false;

        $this->options['jquery_ui_theme'] = array_key_exists('jquery_ui_theme', $options) ? filter_var($options['jquery_ui_theme']) : 'base';

        $this->versionModernizr = (isset($options['modernizr']) && !empty($options['modernizr']) && in_array($options['modernizr'], $this->versionsModernizr)) ? $options['modernizr'] : $this->defaultVersionModernizr;


        if ($this->options['debug']) {
            $this->token = sha1(microtime());
        } else {
            $this->token = (isset($options['token']) && !empty($options['token'])) ? $options['token'] : $this->options['version'];
        }

        $this->Mobile_Detect = new Mobile_Detect();
    }

    public function mergeOptions($options) {
        if (count($options)) {
            $this->options = array_merge($this->options, $options);
        }
    }

    public function getCommonHeader() {

        $heads = array();
        //indicateur dev ou prod
        //Gestion du content-type + title
        $title = strlen($this->options['title']) ? $this->options['title'] : $this->options['default_title'];

        $heads[] = HtmlTag::title($title);

        if ($this->options['favicon']) {
            $favicon = parse_url($this->options['favicon']);
            $favicon = isset($favicon['host']) ? $this->options['favicon'] : $this->options['base_url'] . $this->options['relative_path'] . $this->options['favicon'];
            $heads[] = HtmlTag::link(array('rel' => 'shortcut icon', 'type' => 'image/x-icon', 'href' => $favicon));
        }
        if (isset($this->options['content_type']) && is_array($this->options['content_type'])) {
            $heads[] = HtmlTag::meta($this->options['content_type']);
        } else {
            $heads[] = HtmlTag::meta(array('http-esquiv' => 'Content-Type', 'content' => 'text/html; charset=UTF-8'));
        }


        if (strlen($this->options['meta_description'])) {
            $heads[] = HtmlTag::meta(array('name' => 'description', 'content' => $this->options['meta_description']));
        }
        if (strlen($this->options['meta_keywords'])) {
            $heads[] = HtmlTag::meta(array('name' => 'keywords', 'content' => $this->options['meta_keywords']));
        }

        //Gestion de l'indexation
        if ($this->options['robot']) {
            $heads[] = HtmlTag::meta(array('name' => 'robots', 'content' => 'index,follow'));
        } elseif (strlen($this->options['robots'])) {
            $heads[] = HtmlTag::meta(array('name' => 'robots', 'content' => $this->options['robots']));
        } else {
            $heads[] = HtmlTag::meta(array('name' => 'robots', 'content' => 'none')) . HtmlTag::meta(array('name' => 'robots', 'content' => 'noimageindex'));
        }
        //activation du mode responsive
        if ($this->options['responsive']) {
            $heads[] = HtmlTag::meta(array('name' => 'viewport', 'content' => 'width=device-width,initial-scale=1'));
        }

        //  CSS
        if ($this->options['bootstrap']) {
            if ($this->options['bootstrapByCDN']) {
                if ($this->options['bootstrapFontAwesomeByCND']) {
                    $bootstrapFontAwesomeByCND = is_string($this->options['bootstrapFontAwesomeByCND']) ? $this->options['bootstrapFontAwesomeByCND']:'3.1.1';
                    $heads[] = HtmlTag::link(array('media' => 'all', 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => '//netdna.bootstrapcdn.com/twitter-bootstrap/' . $this->versionBootstrap . '/css/bootstrap-combined.no-icons.min.css'));
                    $heads[] = HtmlTag::link(array('media' => 'all', 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => '//netdna.bootstrapcdn.com/font-awesome/'.$bootstrapFontAwesomeByCND.'/css/font-awesome.css'));
                } else {
                    $heads[] = HtmlTag::link(array('media' => 'all', 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => '//netdna.bootstrapcdn.com/twitter-bootstrap/' . $this->versionBootstrap . '/css/bootstrap-combined.min.css'));
                }
            } else {
                $heads[] = HtmlTag::link(array('media' => 'all', 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => $this->getFrontPath() . 'bootstrap/' . $this->versionBootstrap . '/docs/assets/css/bootstrap.min.css'));
            }
        }
        //activation du mode responsive
        if ($this->options['responsive'] && $this->options['bootstrap'] && !$this->options['bootstrapByCDN']) {
            $heads[] = HtmlTag::link(array('media' => 'all', 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => $this->getFrontPath() . 'bootstrap/' . $this->versionBootstrap . '/docs/assets/css/bootstrap-responsive.min.css'));
        }
        if ($this->options['bootstrap'] && !$this->options['bootstrapByCDN']) {
            $heads[] = HtmlTag::link(array('media' => 'all', 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => $this->getFrontPath() . 'css/bootstrap.fix.css?v=' . $this->token));
        }
        if ($this->options['jquery_mobile']) {
            //$heads[] = HtmlTag::link(array('rel' => 'stylesheet', 'src' => 'http://code.jquery.com/mobile/' . $this->options['jquery_mobile'] . '/jquery.mobile.structure-' . $this->options['jquery_mobile'] . '.min.css'));
            $heads[] = HtmlTag::link(array('rel' => 'stylesheet', 'href' => 'http://code.jquery.com/mobile/1.2.0/jquery.mobile.structure-1.2.0.min.css'));
        }
        if ($this->options['jquery_ui']) {//
            $heads[] = HtmlTag::link(array('media' => 'all', 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => 'http://code.jquery.com/ui/1.10.0/themes/'.$this->options['jquery_ui_theme'].'/jquery-ui.css'));
        }
        // Gestion navigateur
        if ($this->Mobile_Detect->version('MSIE')) {
            $heads[] = HtmlTag::link(array('media' => 'all', 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => $this->getFrontPath() . 'css/ie.css?v=' . $this->token));
//            if ($this->browser['version'] < 9) {
//                if ($this->browser['version'] < 7) {    //Gestion de la transparence des images sous ie6
//                    $heads[] = HtmlTag::script(null, array('type' => 'text/javascript', 'src' => $this->getFrontPath() . 'ie6/iepngfix_tilebg.js?v=' . $this->token));
//                    $heads[] = HtmlTag::style('img, div { behavior: url(' . $this->getFrontPath() . 'ie6/iepngfix.htc); }', array('type' => 'text/css'));
//                }
//                $heads[] = HtmlTag::script(null, array('type' => 'text/javascript', 'src' => 'http://html5shim.googlecode.com/svn/trunk/html5.js'));
//            }
        }

        if($this->options['BootstrapTwitterJS']){
            $heads[] = HtmlTag::link(array('media' => 'all', 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => $this->getFrontPath() . 'css/BootstrapTwitter.css?v=' . $this->token));
        }
        return implode("\n", $heads);
    }

    public function getCommonFooter() {
        $heads = array();
        if ($this->options['browser_update']) {
            $heads[] = HtmlTag::script('var $buoop = {} ;$buoop.ol = window.onload;window.onload=function(){ try {if ($buoop.ol) $buoop.ol();}catch (e) {} var e = document.createElement("script"); e.setAttribute("type", "text/javascript"); e.setAttribute("src", "http://browser-update.org/update.js"); document.body.appendChild(e); }', array('type' => 'text/javascript'));
        }
        //  Bridge JS
        if ($this->options['bridge']) {
            $get = (isset($_GET)) ? $_GET : array();
            $scriptDataServeur = '/**/var Server = ' . json_encode(array('_get' => $get, 'debug' => (integer) $this->options['debug'], 'base_url' => $this->options['base_url'], 'host' => $this->options['host'], 'relative_path' => $this->options['relative_path'])) . ';var Page = ' . json_encode($this->options) . ';/**/';
            $heads[] = HtmlTag::script($scriptDataServeur, array('type' => 'text/javascript'));
        }

        if ($this->options['bootstrap']) {
            if ($this->options['bootstrapByCDN']) {
                $heads[] = HtmlTag::script(null, array('type' => 'text/javascript', 'src' => 'http://code.jquery.com/jquery-' . $this->versionJquery . '.min.js'));
                $heads[] = HtmlTag::script(null, array('type' => 'text/javascript', 'src' => '//netdna.bootstrapcdn.com/twitter-bootstrap/' . $this->versionBootstrap . '/js/bootstrap.min.js'));
            } else {
                $heads[] = HtmlTag::script(null, array('type' => 'text/javascript', 'src' => $this->getFrontPath() . 'bootstrap/' . $this->versionBootstrap . '/docs/assets/js/jquery.js'));
                //<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.0/js/bootstrap.min.js"></script>
                $heads[] = HtmlTag::script(null, array('type' => 'text/javascript', 'src' => $this->getFrontPath() . 'bootstrap/' . $this->versionBootstrap . '/docs/assets/js/bootstrap.min.js'));
            }
            // Gestion ie et companie ...
            if ($this->Mobile_Detect->version('MSIE') && $this->Mobile_Detect->version('MSIE') < 9) {
                $heads[] = HtmlTag::script(null, array('type' => 'text/javascript', 'src' => $this->getFrontPath() . 'ie6/ie6.js?s=' . $this->token));
                $heads[] = HtmlTag::link(array('media' => 'all', 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => $this->getFrontPath() . 'css/ie.css?s=' . $this->token));
            }
        } elseif ($this->options['jquery']) {
            $heads[] = HtmlTag::script(null, array('type' => 'text/javascript', 'src' => 'http://code.jquery.com/jquery-' . $this->versionJquery . '.min.js'));
        }
        if ($this->options['jquery_migrate']) {
            $heads[] = HtmlTag::script(null, array('type' => 'text/javascript', 'src' => 'http://code.jquery.com/jquery-migrate-1.2.1.min.js'));
        }
        if ($this->options['jquery_mobile']) {
            $heads[] = HtmlTag::script(null, array('type' => 'text/javascript', 'src' => 'http://code.jquery.com/mobile/' . $this->options['jquery_mobile'] . '/jquery.mobile-' . $this->options['jquery_mobile'] . '.js'));
        }
        if ($this->options['jquery'] && $this->options['jquery_ui']) {
            $heads[] = HtmlTag::script(null, array('type' => 'text/javascript', 'src' => 'http://code.jquery.com/ui/1.10.3/jquery-ui.min.js'));
        }
        if ($this->options['jquery']) {
            $min = ($this->options['debug']) ? '' : '.min';
            $heads[] = HtmlTag::script(null, array('type' => 'text/javascript', 'src' => $this->getFrontPath() . 'js/common' . $min . '.js?s=' . $this->token));
        }
        if ($this->options['BootstrapTwitterJS']) {
            $heads[] = HtmlTag::script(null, array('type' => 'text/javascript', 'src' => $this->getFrontPath() . 'js/BootstrapTwitter' . $min . '.js?s=' . $this->token));
        }


        return implode('', $heads);
    }

    public function getFrontPath() {
        return $this->options['base_engine'] . 'front/';
    }

    public static function getHighCharts($onlySrc = false) {
        $srcs = array(
            'http://code.highcharts.com/highcharts.js',
            'http://code.highcharts.com/highcharts-more.js',
            'http://code.highcharts.com/modules/exporting.js'
        );
        $return = '';
        if ($onlySrc) {
            return $srcs;
        }
        foreach ($srcs as $src) {
            $return .= HtmlTag::script(null, array('src' => $src));
        }
        return $return;
    }

    public function getJsHtmlFooter() {
        $return = $this->getCommonFooter();
        $return .= HtmlTag::script(null, array('src' => $this->getFrontPath() . 'js/plugin/jquery.inherit.min.js')) .
                HtmlTag::script(null, array('src' => $this->getFrontPath() . 'js/plugin/nano.js')) .
                HtmlTag::script(null, array('src' => $this->getFrontPath() . 'js/html/html.interpreter.js'));
        return $return;
    }

    public function getScript($url = false, $relative = true, $content = null, $attributs = array()) {
        $attributs = array_merge(array('type' => 'text/javascript'), $attributs);
        if ($url) {
            $absoluteUrl = ($relative) ? $this->options['base_url'] . $url : $url;
            $parse_url = parse_url($absoluteUrl);
            $sg = (isset($parse_url['query']) && !empty($parse_url['query'])) ? '&' : '?';
            $attributs['src'] = $absoluteUrl . $sg . 'v=' . $this->token;
        }
        return HtmlTag::script($content, $attributs);
    }

    public function getStyleSheet($url, $relative = true) {
        $absoluteUrl = ($relative) ? $this->options['base_url'] . $url : $url;
        $attributs = array('media' => 'all', 'rel' => 'stylesheet', 'type' => 'text/css');
        $parse_url = parse_url($absoluteUrl);
        $sg = (isset($parse_url['query']) && !empty($parse_url['query'])) ? '&' : '?';
        $attributs['href'] = $absoluteUrl . $sg . 'v=' . $this->token;
        return HtmlTag::link($attributs);
    }

    public function browser_info() {
        $u_agent = $_SERVER['HTTP_USER_AGENT'];
        $bname = 'Unknown';
        $platform = 'Unknown';
        $version = "";

        //First get the platform?
        if (preg_match('/linux/i', $u_agent)) {
            $platform = 'linux';
        } elseif (preg_match('/macintosh|mac os x/i', $u_agent)) {
            $platform = 'mac';
        } elseif (preg_match('/windows|win32/i', $u_agent)) {
            $platform = 'windows';
        }

        // Next get the name of the useragent yes seperately and for good reason
        if (preg_match('/MSIE/i', $u_agent) && !preg_match('/Opera/i', $u_agent)) {
            $bname = 'Internet Explorer';
            $ub = "MSIE";
        } elseif (preg_match('/Firefox/i', $u_agent)) {
            $bname = 'Mozilla Firefox';
            $ub = "Firefox";
        } elseif (preg_match('/Chrome/i', $u_agent)) {
            $bname = 'Google Chrome';
            $ub = "Chrome";
        } elseif (preg_match('/Safari/i', $u_agent)) {
            $bname = 'Apple Safari';
            $ub = "Safari";
        } elseif (preg_match('/Opera/i', $u_agent)) {
            $bname = 'Opera';
            $ub = "Opera";
        } elseif (preg_match('/Netscape/i', $u_agent)) {
            $bname = 'Netscape';
            $ub = "Netscape";
        }

        // finally get the correct version number
        $known = array('Version', $ub, 'other');
        $pattern = '#(?<browser>' . join('|', $known) .
                ')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#';
        if (!preg_match_all($pattern, $u_agent, $matches)) {
            // we have no matching number just continue
        }

        // see how many we have
        $i = count($matches['browser']);
        if ($i != 1) {
            //we will have two since we are not using 'other' argument yet
            //see if version is before or after the name
            if (strripos($u_agent, "Version") < strripos($u_agent, $ub)) {
                $version = $matches['version'][0];
            } else {
                $version = $matches['version'][1];
            }
        } else {
            $version = $matches['version'][0];
        }

        // check if we have a number
        if ($version == null || $version == "") {
            $version = "?";
        }

        return array(
            'userAgent' => $u_agent,
            'name' => $bname,
            'version' => $version,
            'platform' => $platform,
            'pattern' => $pattern
        );
    }

    public function getDisplay($content, $additionalHead = '', $additionalFooter = '', $bodyAttr = array()) {
        $bodyAttr = HtmlTag::addClassAttributs($this->currentPage, $bodyAttr);
        if ($this->Mobile_Detect->version('MSIE')) {
            $bodyAttr = HtmlTag::addClassAttributs('msie msie' . $this->Mobile_Detect->version('MSIE'), $bodyAttr);
        }
        $content = HtmlTag::head($this->getCommonHeader() . $additionalHead) . HtmlTag::body($content . $this->getCommonFooter() . $additionalFooter, $bodyAttr);
        return '<!DOCTYPE HTML>' . HtmlTag::html($content, array('lang' => 'fr', 'xmlns' => 'http://www.w3.org/1999/xhtml'));
    }

    public static function startTime() {
        return microtime(true);
    }

    public static function endTime($onlyElapsed = false, $start_time = false) {
        if (!defined('START_TIME') && $start_time === false) {
            return 'Il faut définir une valeur de début avec START_TIME (voir conf.php)';
        }
        $start_time = $start_time === false ? START_TIME: $start_time;
        $return = "Temps d'exécution : ";
        $endTime = microtime(true);
        $elapsed = $endTime - $start_time;

        $return .= (!$onlyElapsed) ? self::getHumanReadableSecondes($elapsed) : $elapsed;
        return $return;
    }

    public static function getHumanReadableSecondes($time) {
        $tabTemps = array(
            "jours" => 86400,
            "heures" => 3600,
            "minutes" => 60,
            "secondes" => 1);
        $time_first = $time;
        $result = "";

        foreach ($tabTemps as $uniteTemps => $nombreSecondesDansUnite) {
            $$uniteTemps = floor($time / $nombreSecondesDansUnite);

            $time = $time % $nombreSecondesDansUnite;
            if ($$uniteTemps > 0 || !empty($result))
                $result .= $$uniteTemps . " $uniteTemps ";
        }
        //moins d'une seconde
        if (!strlen($result)) {
            $result = round($time_first, 4) . ' seconde';
        }
        return $result;
    }

    public static function sendJson($data, $alt = false, $encode = true) {
        header('Cache-Control: no-cache, must-revalidate');
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        header('Content-type: application/json; charset=utf-8');
        echo $encode ? json_encode($data, $alt) : $data;
        exit;
    }

    public static function sendXml($data) {
        header('Cache-Control: no-cache, must-revalidate');
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        header('Content-type: application/xml; charset=utf-8');
        echo $data;
        exit;
    }

}

?>
